using System;
using System.Collections.Generic;
using System.Text;

namespace A4G.Core
{
	[Serializable]
	public struct Coordinate
	{
		public Coordinate(Coordinate coord)
			: this(coord.X, coord.Y)
		{
		}

		public Coordinate(int x, int y)
		{
			_x = x;
			_y = y;
		}

		public static Coordinate operator + (Coordinate lhs, Coordinate rhs)
		{
			return new Coordinate(lhs.X + rhs.X, lhs.Y + rhs.Y);
		}

		public static Coordinate operator -(Coordinate lhs, Coordinate rhs)
		{
			return new Coordinate(lhs.X - rhs.X, lhs.Y - rhs.Y);
		}

		public static Coordinate operator ++(Coordinate lhs)
		{
			return new Coordinate(lhs.X + 1, lhs.Y + 1);
		}

		public static Coordinate operator --(Coordinate lhs)
		{
			return new Coordinate(lhs.X - 1, lhs.Y - 1);
		}

		private int _x;
		public int X
		{
			get { return _x; }
			set { _x = value; }
		}

		private int _y;
		public int Y
		{
			get { return _y; }
			set { _y = value; }
		}

		public void Limit(Rectangle maxRect)
		{
			maxRect.Normalize();

			if (X < maxRect.X1)
			{
				X = maxRect.X1;
			}
			else if (X > maxRect.X2)
			{
				X = maxRect.X2;
			}

			if (Y < maxRect.Y1)
			{
				Y = maxRect.Y1;
			}
			else if (Y > maxRect.Y2)
			{
				Y = maxRect.Y2;
			}
		}

		public void ApplyTracebackPointer(TracebackPointers pointer, TracebackDirection direction)
		{
			int step = (int)direction;

			switch (pointer)
			{
				case TracebackPointers.None:
					break;

				case TracebackPointers.Match:
				case TracebackPointers.Mismatch:
					X += step;
					Y += step;
					break;

				case TracebackPointers.GapInFirstSequence:
					Y += step;
					break;

				case TracebackPointers.GapInSecondSequence:
					X += step;
					break;

				default:
					break;
			}
		}

		public override string ToString()
		{
			return string.Format("({0},{1})", X, Y);
		}
	}
}
